package thread;

import java.util.Scanner;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 刘远望
 * Date: 2025-05-25
 * Time: 19:07
 */
public class Demo24 {
    public static void main(String[] args) {
        Object locker = new Object();

        Thread thread1 = new Thread(() -> {
            try {
                System.out.println("thread1 wait之前");
                synchronized (locker) {
                    //locker.wait();
                    locker.wait(1000);//同sleep一样超时间等待
                    /**
                     *wait可以使用notify唤醒 也可以被interrupt唤醒
                     * sleep也可以使用interrupt提前唤醒(interrupt本身的作用是通知线程的终止)
                     * 最主要的区别 wait必须要搭配锁 要先加锁才能使用wait 而sleep不用
                     * 如果都是在synchoronized内部使用，wait会释放锁 sleep不会(其他线程不会获得到这个锁)
                     */
                }
                System.out.println("thread1 wait之后");
            }catch (InterruptedException e) {
                throw new RuntimeException();
            }
        });

        Thread thread2 = new Thread(() -> {
            try {
                System.out.println("thread2 wait之前");
                synchronized (locker) {
                    locker.wait();
                }
                System.out.println("therad2 wait之后");
            }catch (InterruptedException e) {
                throw new RuntimeException();
            }
        });

        Thread thread3 = new Thread(() -> {
            Scanner scanner = new Scanner(System.in);
            System.out.println("任意输入唤醒其中一个线程");
            scanner.next();
            synchronized (locker) {
                locker.notifyAll();//同时唤醒t1和t2
                /**
                 * 等wait唤醒之后需要重新加锁
                 * 其中一个线程还是要加上锁 开始执行 另一个线程加锁失败就会再次阻塞等待
                 * 等先走的线程解锁 后走的线程才能加上锁继续执行
                 */
            }
           /* synchronized (locker) {
                locker.notify();
            }
            System.out.println("任意输入唤醒另一个线程");
            scanner.next();
            synchronized (locker) {
                locker.notify();
            }*/
        });

        thread1.start();
        thread2.start();
        /**
         * 实际上同一个对象可以wait多次 每一次notify随机唤醒一个(操作系统的随机调度原因)
         * 所以这些wait的线程都是干同样的工作 唤醒谁都一样
         */
        thread3.start();
    }
}
